package com.aliyun.edu.advanced.development.thread.sync.deadlock;

/**
 * @author xiaoming
 * @version 1.0
 * @date 2019-02-23 15:50
 * 课时35 线程的同步与死锁（同步问题引出）
 * 课时36 线程的同步与死锁（同步处理）
 *
 **/
public class Demo1Sync {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        new Thread(mt, "票贩子A") .start();
        new Thread(mt, "票贩子B") .start();

        // 加锁会导致执行速度变慢
    }

}
// 未加锁 (同步问题出现)
class MyThread implements Runnable {
    // 票总数
    private int ticket = 10;
    @Override
    public void run() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            // 判断: 还有票
            if (this.ticket > 0) {
                try {
                    // 模拟网络延迟 (只是加重问题的出现)
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 卖票 ticket = " + this.ticket--);
            }
        }

        System.out.println("余票: " + ticket);
    }
}

/**
 * 同步代码块
 */
class MyThread1 implements Runnable {
    // 票总数
    private int ticket = 10;
    @Override
    public void run() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            // 判断: 还有票
            // 加锁: 在同一时刻只能允许一个线程进入并操作, 其他线程需要等待
            synchronized (this) {
                if (this.ticket > 0) {
                    try {
                        // 模拟网络延迟 (只是加重问题的出现)
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " 卖票 ticket = " + this.ticket--);
                }
            }
        }
        System.out.println("结束:余票: " + ticket);
    }
}



/**
 * 方法加锁
 */
class MyThread2 implements Runnable {
    // 票总数
    private int ticket = 10;
    @Override
    public void run() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            this.sale();
        }
        System.out.println("余票: " + ticket);
    }

    // 加锁方法 (同步方法)
    public synchronized void sale() {
        // 判断: 还有票
        if (this.ticket > 0) {

            try {
                // 模拟网络延迟
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "卖票 ticket = " + this.ticket--);
        }
    }
}
